package de.mhus.lib.mandala.bind;

import java.io.PrintWriter;

import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;

import de.mhus.lib.mandala.Attribute;
import de.mhus.lib.mandala.Response;
import de.mhus.lib.mandala.functions.FunctionCall;
import de.mhus.lib.mandala.impl.WindowExtended;

public class DynamicSingleDataSource extends SingleDataSourceAction implements RemoteCallable {

	private Attribute target = new Attribute();
	private FunctionCall errorCall;
	private FunctionCall successCall;
	private RemoteRegistry registry;

	@Override
	protected void doRender(Response out) {

		if (registry == null)
			registry = getWindow().registerRemoteCall(this);
		
		out.println("function(data) {");
		out.print("  var url = '");
		out.print(registry.getUrl());
		out.print("&_mandala_request_id='+ Math.random() +'");
		out.println("&data=' + encodeURIComponent(JSON.stringify(data));");
		if (getWindow() instanceof WindowExtended) ((WindowExtended)getWindow()).beforeRemoteCall(out,"url");
		out.println("  $.getJSON(url, function (data2) {");
		if (getWindow() instanceof WindowExtended) ((WindowExtended)getWindow()).afterRemoteCall(out,"data2");
		out.println("        if (data2.success == 1 && data2.result && data2.result[0]) {");
		target.renderElementName(out);
		out.print("(data2.result[0]);");
		if (getSuccessCall() != null) getSuccessCall().doRender(getWindow(), out);
		out.println("} else {");
		if (errorCall != null) errorCall.doRender(getWindow(), out);
		out.println("} }); }");
		
	}

	public FunctionCall getErrorCall() {
		return errorCall;
	}

	public void setErrorCall(FunctionCall errorCall) {
		this.errorCall = errorCall;
	}


	public FunctionCall getSuccessCall() {
		return successCall;
	}

	public void setSuccessCall(FunctionCall successCall) {
		this.successCall = successCall;
	}

	@Override
	public void doRemoteCall(JsonNode in, JsonGenerator out, String requestId) throws Exception {
		ObjectMapper mapper = new ObjectMapper();
		ObjectNode node = mapper.createObjectNode();
		node.put("requestId", requestId);
		try {
			
			ArrayNode result = node.putArray("result");

			DataRow item = getProvider().getData(in);
			ObjectNode next = result.addObject();
			if (item != null) item.fill(next);
			
			node.put("success", 1);
		} catch (Throwable t) {
			node.put("success", 0);
			node.put("error_msg", t.getMessage());
			t.printStackTrace();
		}
		
		out.setCodec(mapper);
		out.writeTree(node);

	}
	
	public Attribute getTarget() {
		return target;
	}

	public void setTarget(Attribute target) {
		this.target = target;
	}

}
